/*
 * @depends *
 */
// Prevent combobox z-indez when in nested window
Ext.override(Ext.form.ComboBox, {
    getParentZIndex : function(){
        var zindex = 0;
        if (this.ownerCt){
            this.findParentBy(function(ct){
                zindex = Math.max(zindex, parseInt(ct.getPositionEl().getStyle('z-index'), 10));
                //return !!zindex;
            });
        }
        return zindex;
    }
});

// Prevent combo getValue behavior
Ext.override(Ext.form.BasicForm, {
	updateRecord : function(record){	
	    record.beginEdit();
	    var fs = record.fields,
	        field,
	        value;
	    fs.each(function(f){
	        field = this.findField(f.name);
	        if(field){
	            value = field.getValue();
	            if (value && typeof value != undefined && value.getGroupValue) {
	                value = value.getGroupValue();
	            } else if ( field.eachItem ) {
	                value = [];
	                field.eachItem(function(item){
	                    value.push(item.getValue());
	                });
	            } else if ( typeof field.selectedIndex != undefined && Ext.isEmpty(value) ) {
	            	value = null;
	            }
	            record.set(f.name, value);
	        }
	    }, this);
	    record.endEdit();
	    return this;
	}
});

// Normalize exception behavior of DirectProxy
Ext.override(Ext.data.DirectProxy, {
	/**
     * Callback for read actions
     * @param {String} action [Ext.data.Api.actions.create|read|update|destroy]
     * @param {Object} trans The request transaction object
     * @param {Object} result Data object picked out of the server-response.
     * @param {Object} res The server response
     * @protected
     */
    onRead : function(action, trans, result, res) {
        var success = trans.reader.getSuccess(result);
        if (success) {
	        var records = trans.reader.readRecords(result);
	        this.fireEvent("load", this, res, trans.request.arg);
	        trans.request.callback.call(trans.request.scope, records, trans.request.arg, true);
        } else {
            // @deprecated: Fire old loadexception for backwards-compat.
            this.fireEvent("loadexception", this, trans, res);

            this.fireEvent('exception', this, 'response', action, trans, res);
            trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
            return;
        }
    },
	/**
	 * Callback for write actions
	 * @param {String} action [{@link Ext.data.Api#actions create|read|update|destroy}]
	 * @param {Object} trans The request transaction object
	 * @param {Object} result Data object picked out of the server-response.
	 * @param {Object} res The server response
	 * @param {Ext.data.Record/[Ext.data.Record]} rs The Store resultset associated with the action.
	 * @protected
	 */
	onWrite : function(action, trans, result, res, rs) {
        var success = trans.reader.getSuccess(result);
        if (success) {
			var data = trans.reader.extractData(trans.reader.getRoot(result), false);
			this.fireEvent("write", this, action, data, res, rs, trans.request.arg);
			trans.request.callback.call(trans.request.scope, data, res, true);
        } else {
        	// @deprecated: Fire old loadexception for backwards-compat.
	        this.fireEvent("loadexception", this, trans, res);

	        this.fireEvent('exception', this, 'remote', action, trans, res);
	        trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
        }
	}
});

//Add silent (don't focus) node selection.
Ext.override(Ext.tree.TreeNodeUI, {
    onSilentSelectedChange : function(state){
        if(state){
        	this.focusSilent();
            this.addClass("x-tree-selected");
        }else{            
            this.removeClass("x-tree-selected");
        }
    },
    
    // private
    focusSilent : function(){
        if(!this.node.preventHScroll){
            try{this.anchor.scrollIntoViewIfNeeded();
            }catch(e){}
        }else{
            try{
                var noscroll = this.node.getOwnerTree().getTreeEl().dom;
                var l = noscroll.scrollLeft;
                this.anchor.scrollIntoViewIfNeeded();
                noscroll.scrollLeft = l;
            }catch(e){}
        }
    }
});

//Add silent (don't focus) node selection.
Ext.override(Ext.tree.DefaultSelectionModel, {
	   /**
     * Select a node.
     * @param {TreeNode} node The node to select
     * @return {TreeNode} The selected node
     */
    selectSilent : function(node, /* private*/ selectNextNode){
        // If node is hidden, select the next node in whatever direction was being moved in.
        if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) {
            return selectNextNode.call(this, node);
        }
        var last = this.selNode;
        if(node == last){
            node.ui.onSilentSelectedChange(true);
        }else if(this.fireEvent('beforeselect', this, node, last) !== false){
            if(last && last.ui){
                last.ui.onSilentSelectedChange(false);
            }
            this.selNode = node;
            node.ui.onSilentSelectedChange(true);
            this.fireEvent('selectionchange', this, node, last);
        }
        return node;
    }
});

// Add silent (don't focus) node selection.
Ext.override(Ext.tree.TreeNode, {
	/*
    * Triggers selection of this node
    */
   selectSilent : function(){
       var t = this.getOwnerTree();
       if(t){
           t.getSelectionModel().selectSilent(this);
       }
   }
});

// Prevent child window 'maxime' problem. 
Ext.override(Ext.Window, {
	   /**
     * Fits the window within its current container and automatically replaces
     * the {@link #maximizable 'maximize' tool button} with the 'restore' tool button.
     * Also see {@link #toggleMaximize}.
     * @return {Ext.Window} this
     */
    maximize : function(){
        if(!this.maximized){
            this.expand(false);
            this.restoreSize = this.getSize();
            this.restorePos = this.getPosition(true);
            if (this.maximizable){
                this.tools.maximize.hide();
                this.tools.restore.show();
            }
            this.maximized = true;
            this.el.disableShadow();

            if(this.dd){
                this.dd.lock();
            }
            if(this.collapsible){
                this.tools.toggle.hide();
            }
            //this.el.addClass('x-window-maximized');
            //this.container.addClass('x-window-maximized-ct');

            this.setPosition(0, 0);
            this.fitContainer();
            this.fireEvent('maximize', this);
        }
        return this;
    },

    /**
     * Restores a {@link #maximizable maximized}  window back to its original
     * size and position prior to being maximized and also replaces
     * the 'restore' tool button with the 'maximize' tool button.
     * Also see {@link #toggleMaximize}.
     * @return {Ext.Window} this
     */
    restore : function(){
        if(this.maximized){
            var t = this.tools;
            //this.el.removeClass('x-window-maximized');
            if(t.restore){
                t.restore.hide();
            }
            if(t.maximize){
                t.maximize.show();
            }
            this.setPosition(this.restorePos[0], this.restorePos[1]);
            this.setSize(this.restoreSize.width, this.restoreSize.height);
            delete this.restorePos;
            delete this.restoreSize;
            this.maximized = false;
            this.el.enableShadow(true);

            if(this.dd){
                this.dd.unlock();
            }
            if(this.collapsible && t.toggle){
                t.toggle.show();
            }
            //this.container.removeClass('x-window-maximized-ct');

            this.doConstrain();
            this.fireEvent('restore', this);
        }
        return this;
    }
});

Ext.apply(Ext.form.VTypes, {
    daterangecomposite : function(val, field) {
        var date = field.parseDate(val);
 
        if (!date)
            return false;

        if (field.startDateField && (!this.dateRangeMax || (date.getTime() != this.dateRangeMax.getTime()))) {			
            var start = Ext.getCmp(field.startDateField);
            start.setMaxValue(date);
            start.validate();
            this.dateRangeMax = date;
        } 
        else if (field.endDateField && (!this.dateRangeMin || (date.getTime() != this.dateRangeMin.getTime()))) {			
            var end = Ext.getCmp(field.endDateField);
            end.setMinValue(date);
            end.validate();
            this.dateRangeMin = date;
        }
        /*
         * Always return true since we're only using this vtype to set the
         * min/max allowed values (these are tested for after the vtype test)
         */
        return true;
    },
    
    // Password Check
    passwordText: 'The passwords entered does not match.',
    password: function(value, field) {
        var valid = false;
        if (field.matches) {
            var otherField = Ext.getCmp(field.matches);
            if (value == otherField.getValue()) {
                otherField.clearInvalid();
                valid = true;
            }
        }
        return valid;
    }
});